import typing
from datetime import datetime
from enum import Enum
from typing import Optional, List, Union

from pydantic import validator, BaseModel, Field, conint

from exceptions import InvalidParam
from models.administrative_division import DivisionRegion
from models.common import OID, RWModel
from utils.dateutil import date_now
from utils.dbutil import convert2sort


class AlumniBasicModel(RWModel):
    id: Optional[OID]
    # 是否已删除


class AlumniModel(AlumniBasicModel):
    person_id: Optional[OID]


class GenderType(str, Enum):
    female = "female"
    male = "male"
    other = "other"


class Alumni(AlumniBasicModel):
    person_code: Optional[str]
    name_zh: Optional[str]
    name: Optional[str]
    identify_type: Optional[str]
    identify_id: Optional[str]
    self_label: Optional[str]
    identify_photo: Optional[Union[str]]
    age: Optional[int]
    level_of_role: Optional[str]
    gender: Optional[str]
    birthday: Optional[datetime]
    nationality: Optional[str]
    native_place: Optional[DivisionRegion]
    native_place_code: Optional[str]
    political_status: Optional[str]
    nation: Optional[str]
    cur_institution_id: Optional[str]
    cur_institution_name: Optional[str]
    cur_institution_department: Optional[str]
    job_title: Optional[List[str]]  # str to list # 职务
    professional_titles: Optional[List[str]]  # str to list # 职称
    email: Optional[List[str]]  # str to list
    job_level: Optional[str]
    graduate_school: Optional[str]
    speciality_id: Optional[str]
    degree: Optional[str]
    academic_qualification: Optional[str]  # deprecated
    alumni_score: Optional[float] = 0  # 身份值
    num_of_activities: Optional[int] = 0
    cumulative_hours: Optional[float]
    identity_value: Optional[float]
    phone: Optional[str]
    fax: Optional[str]
    contact_address: Optional[str]
    zip_code: Optional[str]
    bio: Optional[str]
    academic_area: Optional[List[str]]  # 从事领域
    research_interests: Optional[str]  # 研究兴趣
    secretary_email: Optional[str]
    secretary_phone: Optional[str]
    cur_address_code: Optional[str]
    academic_position: List[str] = Field(default=None, description="学术组织任职")
    subject: List[str] = Field(default=None, description="学科")
    landline: Optional[List[str]] = Field(default=None, description="国定电话", max_length=16)
    wx_id: Optional[List[str]] = Field(default=None, description="微信ids")  # str to list
    role: Optional[str] = Field(default=None, description="参加角色身份", max_length=128)
    job_city: Optional[str]  # location_city
    job_province: Optional[str]  # location_city
    jobs_about_cast: Optional[List[str]]
    person_labels: Optional[List[str]]
    term_of_jobs_about_cast: Optional[List[str]]
    term_number_of_jobs_about_cast: Optional[List[str]]
    update_time: Optional[datetime]

    # todo 把活动人才的关联的活动重要性同步写到人身上.
    jobs_about_cast: Optional[List[typing.Any]]
    # force 1:单挑/0 多条
    overwrite: Optional[bool]

    belongs_inst: List[Optional[OID]] = []

    @validator("update_time", pre=True, always=True)
    def val_update_time(cls, v):
        if not v:
            return date_now()

        return v


class AlumniUpdateModel(Alumni):
    id: OID


class AlumniInsertModel(Alumni):
    name_zh: str
    cur_institution_id: Optional[str]
    cur_institution_name: str


class BaseSearchModel(BaseModel):
    offset: conint(ge=0, le=2**32) = 0
    size: conint(ge=0, le=50) = 10
    fields: Optional[List[str]] = None
    is_deleted: Optional[bool] = False
    sort: Optional[List[str]]
    query: Optional[dict]
    aggs: Optional[List[str]]

    @validator('offset', "size")
    def no_negative_number(cls, v):
        if v < 0:
            raise InvalidParam("offset/size", "offset/size should be positive number")
        return v

    @validator('sort')
    def parse_sort_value(cls, v):
        return convert2sort(v)


class AlumniSearchModel(BaseSearchModel):
    name: Optional[str]
    job_title: Optional[str]
    cur_institution_name: Optional[str]
    region: Optional[str]
    institution_id: Optional[str]
    self_label: Optional[str]


if __name__ == '__main__':
    print(Alumni.fields_check())
